package com.bjsxt;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.bjsxt.fall.RpcBlockHandlerConfig;
import com.bjsxt.fall.RpcFallbackConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@RestController
public class SentinelConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(SentinelConsumerApplication.class ,args) ;
    }

    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        return  new RestTemplate() ;
    }
    @Autowired
    private RestTemplate restTemplate ;

    /**
     * fallback 和 blockHandler 都是回退的机制
     * fallback ： 当前方法发送一个异常 ，它将会走fallback 里面填的方法
     * blockHandler：当该方法触发某种限流、降级规则后走的回退方法
     * fallback 和 blockHandler 都要填方法的名称 ，要填的方法必须和当前的方法在一个类里面 ，而且要和当前的方法的返回值类型，
     * 参数类型保持一致才有效果
     *
     * @param type
     * @return
     */

    @SentinelResource(
                value = "rpc",
                fallbackClass = RpcFallbackConfig.class ,
                fallback = "rpcFallback",
                blockHandlerClass = RpcBlockHandlerConfig.class ,
                blockHandler = "rpcBlockHandler")
    @GetMapping("/rpc")
    public ResponseEntity<String> rpc(@RequestParam(required = true) String type){

        if("java".equals(type)){
            throw new RuntimeException("不想成功") ;
        }
        // 远程调用服务提供者
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(
                "http://sentinel-provider/test",
                String.class);
        if(responseEntity.getStatusCode()== HttpStatus.OK){
            return ResponseEntity.ok("远程调用成功，结果为："+responseEntity.getBody()) ;
        }
        throw new RuntimeException("远程调用失败") ;
    }



}
